'''
QuartoGame.py

Class for the QuartoGame object
'''

import math

from QuartoBoard import *
from QuartoPiece import *

class QuartoGame:
    def __init__(self):
        self.board = QuartoBoard()
        self.turn = 0
        self.availablePieces = []
        self.buildPieces()
        self.history = [] # ordered list of placed pieces and their (x,y) tuple location
        self.selectedPiece = None
        
    def buildPieces(self):
        i = 0
        while i < 16:
            attr_val = self.int2bin(i)
            self.availablePieces.append(QuartoPiece(attr_val[0], attr_val[1], attr_val[2], attr_val[3]))
            i += 1
    
    def nextTurn(self):
        self.turn = int(math.fabs(self.turn - 1))
    
    def isWon(self):
        if len(self.availablePieces) > 12:
            # you can't win without putting down 4 pieces
            return False
        else:
            attr = 0
            while attr < 4:
                i = 0
                while i < 4:
                    four_sum = 0
                    for p in self.board.spots[i][:]:
                        if p : four_sum += int(p.attributes[attr])
                        else : four_sum +=5     
                    if four_sum == 0 or four_sum == 4:
                        print "four_sum = %i, i = %i, attr = %i" % (four_sum,i,attr)
                        return True
                    
                    four_sum = 0
                    for p in self.board.spots[:][i]:
                        if p : four_sum += int(p.attributes[attr])
                        else : four_sum +=5      
                    if four_sum == 0 or four_sum == 4:
                        print "four_sum = %i, i = %i, attr = %i" % (four_sum,i,attr)
                        return True
                    
                    i +=1
                    
                # for the diagonal
                i = 0
                while i < 4:
                    four_sum = 0
                    if self.board.spots[i][i] : four_sum += int(self.board.spots[i][i].attributes[attr])
                    else : four_sum +=5      
                    if four_sum == 0 or four_sum == 4:
                        print "four_sum = %i, i = %i, attr = %i" % (four_sum,i,attr)
                        return True
                    
                    i += 1
                    
                i = 0
                while i < 4:
                    four_sum = 0
                    if self.board.spots[i][int(math.fabs(i-3))] : four_sum += int(self.board.spots[i][int(math.fabs(i-3))].attributes[attr])
                    else : four_sum +=5      
                    if four_sum == 0 or four_sum == 4:
                        print "four_sum = %i, i = %i, attr = %i" % (four_sum,i,attr)
                        return True
                    
                    i += 1
                     
                attr +=1
        return False
 
    
        
    def isDraw(self):
        if not self.isWon():
            if len(self.availablePieces) == 0:
                return True
        return False
        
    def isGameOver(self):
        if self.isWon():
            return True
        if self.isDraw():
            return True
        return False
        
    def selectPiece(self, piece_num):
        if piece_num < len(self.availablePieces):
            self.selectedPiece = self.availablePieces.pop(piece_num)
            return True
        return False
    
    def placePiece(self,x,y):
        if self.selectedPiece:
            if self.board.placePiece(self.selectedPiece,x,y):
                self.selectedPiece.placedBy = self.turn
                self.selectedPiece.onBoard = True
                self.history.append((deepcopy(self.selectedPiece),(x,y))) # add move to history
                self.selectedPiece = None # clear selected piece in game
                return True
        return False
		
	def getState(self):
		return (self.board, self.selectedPiece)
		                
    
    def displayAvailablePieces(self):
        x = 0
        for p in self.availablePieces:
            print "%i = " % (x)
            x += 1 
            p.displayPiece()
    
    def displayBoard(self):
        self.board.displayBoard()
    
    # General Functions
    
    def int2bin(self, n, count=4):
        return "".join([str((n >> y) & 1) for y in range(count - 1, -1, -1)])
        
